#include <EEPROM.h>


#define RANDOMMM 4       //点击随机时间幅度，3~10

float p1 = 7.11;         //点击频率1，
float p2 = 8.55;         //点击频率2，
float p3 = 9.55;         //点击频率2，

//长按随机时间最小值和最大值，50~150
int minTTime0 = 65;
int maxTTime0 = 85;

int minTTime1 = 58;
int maxTTime1 = 67;

int minTTime2 = 55;
int maxTTime2 = 60;






#define MAXFQUNUMBER 3    
float fquList[MAXFQUNUMBER] = {p1,p2,p3};   
int TTtime[MAXFQUNUMBER][2] = {{minTTime0,maxTTime0},{minTTime1,maxTTime1},{minTTime2,maxTTime2}};

#define pinnumber 4
#define vpnumber  9
const int tPin[pinnumber][2] = {{2,3},{4,5},{6,7},{8,9}};  //1号引脚定义,灰的在前，白的在后,电阻接白线
const int tvpin[vpnumber] = {0x08,0x04,0x02,0x01,0x0c,0x06,0x03,0x09,0x0f};
/*

  1     2

  4     3

  1:(1),2:(2),3:(3),4:(4),5:(1,2),6:(2,3),7:(3,4),8:(1,4),9:(1,2,3,4)

*/

#define RCVBUFERSIZE 256
int fquIndex = 0;                          //当前点击频率编号
int eepaddr = 0;
//接收数据缓存
char RCVBUFF[RCVBUFERSIZE] = {0,};

void cleanReviceBuf(){
  for(int i = 0;i < 256;i++){
      RCVBUFF[i]  = '\0';
   }
}
void setTouchData();
void updateRandomTime(int index);

bool readSetDataFromFile(){
  cleanReviceBuf();
  if (EEPROM.read(0)){
      for(int i = 0;i < RCVBUFERSIZE;i++){   
        RCVBUFF[i] = EEPROM.read(i);
      }
      return true;
  }
  return false;
  
}
void saveSetDataToFile(){
  for(int i = 0;i < RCVBUFERSIZE;i++){
    EEPROM.write(i,RCVBUFF[i]);
  }
}

void cleanAllTouch(){
  for(int i = 0;i<pinnumber;i++){
    digitalWrite(tPin[i][1], LOW);
    digitalWrite(tPin[i][0], HIGH);
  }
}

void touchPinHex(int p){
  if(p&0x08){
    digitalWrite(tPin[0][1], HIGH);
    digitalWrite(tPin[0][0], LOW);  
  }
  if(p&0x04){
    digitalWrite(tPin[1][1], HIGH);
    digitalWrite(tPin[1][0], LOW);  
  }
  if(p&0x02){
    digitalWrite(tPin[2][1], HIGH);
    digitalWrite(tPin[2][0], LOW);  
  }
  if(p&0x01){
    digitalWrite(tPin[3][1], HIGH);
    digitalWrite(tPin[3][0], LOW);  
  }
}

void unTouchPinHex(int p){
  if(p&0x08){
    digitalWrite(tPin[0][0], HIGH);
    digitalWrite(tPin[0][1], LOW);  
  }
  if(p&0x04){
    digitalWrite(tPin[1][0], HIGH);
    digitalWrite(tPin[1][1], LOW);  
  }
  if(p&0x02){
    digitalWrite(tPin[2][0], HIGH);
    digitalWrite(tPin[2][1], LOW);  
  }
  if(p&0x01){
    digitalWrite(tPin[3][0], HIGH);
    digitalWrite(tPin[3][1], LOW);  
  }
}

void touchPin(int p){
  if(p >=0 && p <vpnumber){
    touchPinHex(tvpin[p]);
  }
}
void unTouchPin(int p){
    
if(p >=0 && p <vpnumber){
    unTouchPinHex(tvpin[p]);
  }
}

const int blinkdelay = 300;

void ledBlink(){
  for(int i = 0;i<fquIndex+1;i++){
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(blinkdelay);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(blinkdelay); 
  }
}

#define KeyPin  11     //按键开关引脚定义，红色
#define FkeyPin A5     //频率切换按键，白色


void setup() {
  //初始化串口
  Serial.begin(115200);

  //设置随机数种子
  randomSeed(analogRead(A0));
  pinMode(KeyPin, INPUT_PULLUP); //设置按键引脚为输入
  pinMode(FkeyPin, INPUT); //设置按键引脚为输入

  pinMode(LED_BUILTIN, OUTPUT);
  //设置点击头控制引脚为输出
  for(int i = 0;i<pinnumber;i++){
    pinMode(tPin[i][0], OUTPUT);
    pinMode(tPin[i][1], OUTPUT);
  }
  delay(1);
  
  //初始化点击头状态,清除所有当关点击状态
  cleanAllTouch();
  digitalWrite(LED_BUILTIN, LOW);

  if(readSetDataFromFile()){
    setTouchData();
  }  
  
}


int minTime = int(500/fquList[fquIndex]) - RANDOMMM;  //最小随机间隔时间
int maxTime = int(500/fquList[fquIndex]) + RANDOMMM;  //最大随机间隔时间

int ttmindelay = TTtime[fquIndex][0];
int ttmaxdelay = TTtime[fquIndex][1];


//通过频率更新随机间隔时间
void updateRandomTime(int index){
  float f = fquList[index];
  minTime = int(500/f) - RANDOMMM;  //最小随机间隔时间
  maxTime = int(500/f) + RANDOMMM;  //最大随机间隔时间
  ttmindelay = TTtime[index][0];
  ttmaxdelay = TTtime[index][1];
}
int ttime = 125;
int utime = 125;

uint8_t tmpcount = 0;
int isRcvTime = 0;


//字符转数字
int char2int(char input)
{
  if (input >= '0' && input <= '9')
    return input - '0';
  if (input >= 'A' && input <= 'F')
    return input - 'A' + 10;
  if (input >= 'a' && input <= 'f')
    return input - 'a' + 10;
  return 0;
}

float tmpFloat = 0.0;
int tmpNumber = 0;
void setData(int n){
    switch(n){
      case 0:
      {
        p1 = tmpFloat;
      }break;
      case 1:
      {
        p2 = tmpFloat;          
      }break;
      case 2:
      {
        p3 = tmpFloat;
      }break;
      case 3:
      {
        minTTime0 = tmpNumber;
      }break;
      case 4:
      {
        maxTTime0 = tmpNumber;
      }break;
      case 5:
      {
        minTTime1 = tmpNumber;
      }break;
      case 6:
      {
        maxTTime1 = tmpNumber;
      }break;
      case 7:
      {
        minTTime2 = tmpNumber;
      }break;
      case 8:
      {
        maxTTime2 = tmpNumber;
      }break;
      default:
      break;      
    }
        
    fquList[0] = p1;   
    fquList[1] = p2; 
    fquList[2] = p3; 
    TTtime[0][0] = minTTime0;
    TTtime[0][1] = maxTTime0;
    TTtime[1][0] = minTTime1;
    TTtime[1][1] = maxTTime1;
    TTtime[2][0] = minTTime2;
    TTtime[2][1] = maxTTime2;
}

char buftmp[10] = {0,};
void cleanBufemp(){
  for(int i = 0;i < 10;i++){
      buftmp[i]  = '\0';
   }
}


void setTouchData(){
  Serial.println(RCVBUFF);
  saveSetDataToFile();  
  char* p = RCVBUFF;
  int ipx = 0;
  int itmp = 0;
  int pNumber = 0;   
  while(*p){
      if(*p != ','){
        buftmp[ipx] = *p;
        ipx++;
      }else{
        if(pNumber < 3){
          tmpFloat = atof(buftmp);
        }else{
          tmpNumber = atoi(buftmp);
        }
        setData(pNumber);
        // Serial.print(pNumber);
        // Serial.print(' ');
        // Serial.print(buftmp);
        // Serial.print(' ');
        // Serial.print(tmpFloat);
        // Serial.print(' ');
        // Serial.println(tmpNumber);
        pNumber++;
        ipx = 0;   
        cleanBufemp();  
           
        }
      itmp++;
      p++;
      if(*p == '\0' || itmp >= tmpcount){
        break;
      }
  }
  cleanReviceBuf();
  updateRandomTime(fquIndex);
}

void loop() {
  int k = digitalRead(KeyPin);
  if(!k){
    int p = random(0,vpnumber);               //取随机按键
    ttime = random(ttmindelay,ttmaxdelay);   //取随机时间
    touchPin(p);
    delay(ttime);
    utime = random(minTime,maxTime);   //取随机时间
    unTouchPin(p);
    delay(utime);
  }else{
    int fk = digitalRead(FkeyPin);
    if(!fk){
        fquIndex++;
        if(fquIndex >= MAXFQUNUMBER){
          fquIndex = 0;
          updateRandomTime(fquIndex);
        }else{
          updateRandomTime(fquIndex);
        }
        ledBlink();
        Serial.print(fquIndex);
        delay(10);
    }
  }
  if (Serial.available() > 0) {
        delay(1); // 等待数据传完
        while(Serial.available()){
              char tmpdat = Serial.read();
              if(tmpdat == '{'){
                  tmpcount = 0;
                  isRcvTime = 1; //为设置参数
                  continue;
              }else if(tmpdat == '}'){
                  isRcvTime = 0;
                  RCVBUFF[tmpcount] = '\0';
                  setTouchData();
                  tmpcount = 0;
                  break;
              }
              if(!isRcvTime){ //调试模式接收数据，接收到什么返回什么
                   Serial.print(tmpdat);
              }else{
                   RCVBUFF[tmpcount] = tmpdat;
                   tmpcount++;
                   continue;
              }
        }  
  }
}
